#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <vector>
#include <mutex>
#include <queue>
#include <thread>
#include <memory>
#include <condition_variable>
#include <unistd.h>
#include <pthread.h>
#include "Log.hpp"
const int default_thread_num = 10;
using namespace ns_log;


template <class T>
class ThreadPool
{
private:
    // 任务队列
    std::queue<T> _task_queue;
    // 锁
    std::mutex _mtx;
    // 条件变量
    std::condition_variable _con;
    // 管理线程的结构
    std::vector<std::thread> _threads;
    bool _isrunning;
    // 睡眠的线程数量
    int _sleep_threads;
    int _threadsNums;
    static ThreadPool<T>* _pool; 
    static std::mutex _mutex;
private:
    void HandlerTask()
    {
        while (true)
        {
            std::unique_lock<std::mutex> lock(_mtx);
            while (_task_queue.empty() && _isrunning)
            {
                _con.wait(lock);
                // _sleep_threads--;
                break;
            }
            if ((!_isrunning) && _task_queue.empty())
            {
                lock.unlock();
                LOG(DEBUG, "thread pool is quit!\n");
                break;
            }
            T task = _task_queue.front();
            _task_queue.pop();
            lock.unlock();
            task();
        }
    }

public:
    static ThreadPool<T>* GetThreadPoolInstance(int threadnum = default_thread_num)
    {
        //双重检查锁定模式
        if(_pool == nullptr)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            if(_pool == nullptr)
                _pool = new ThreadPool<T>(threadnum);
        }
        return _pool;
    }
    ThreadPool(int threadnum)
        : _isrunning(true),
          _sleep_threads(threadnum),
          _threadsNums(default_thread_num)
    {
        for (int i = 0; i < _threadsNums; i++)
        {
            _threads.emplace_back(std::bind(&ThreadPool::HandlerTask,this));
        }
    }
    //向任务队列插入任务
    void Push(const T &task)
    {
        std::unique_lock<std::mutex> lock(_mtx);
        _task_queue.push(task);
        LOG(DEBUG,"Load once Task!,队列中的任务数量:%d\n",_task_queue.size());
        // 有任务立即通知消费者
        _con.notify_one();
    }
    //停止线程池
    void Stop()
    {
        std::unique_lock<std::mutex> lock(_mtx);
        _isrunning = false;
        _con.notify_all();
    }
    ~ThreadPool()
    {
        for(auto& thread : _threads)
        {
            LOG(DEBUG,"thread join done!\n");
            thread.join();
        }
    }

};

//类外初始化
template<class T>
ThreadPool<T>* ThreadPool<T>::_pool = nullptr;
template<class T>
std::mutex ThreadPool<T>::_mutex;